using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using S.M.SmartMedical.API.Read.Application.Query;
using S.M.SmartMedical.Domain.DTOs;
using S.M.SmartMedical.Domain.Entities;
using S.M.SmartMedical.ErrorCode;
using S.M.SmartMedical.Infrastructure.BaseRepository;

namespace S.M.SmartMedical.API.Read.Application.Handler
{
    /// <summary>
    /// 获取轮播图列表查询处理器
    /// </summary>
    public class GetCarouselsHandler : IRequestHandler<GetCarouselsQuery, APIResult<PagedResult<CarouselDto>>>
    {
        private readonly IRepository<Carousel> _carouselRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<GetCarouselsHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="carouselRepository">轮播图仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetCarouselsHandler(
            IRepository<Carousel> carouselRepository,
            IMapper mapper,
            ILogger<GetCarouselsHandler> logger)
        {
            _carouselRepository = carouselRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取轮播图列表查询
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>轮播图列表响应</returns>
        public async Task<APIResult<PagedResult<CarouselDto>>> Handle(GetCarouselsQuery request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取轮播图列表，搜索关键词：{SearchKeyword}", request.Title);

                // 构建查询条件
                var query = _carouselRepository.GetAllAsync()
                    .Where(x => !x.IsDeleted); // 过滤已删除的轮播图

                // 如果有标题关键词
                if (!string.IsNullOrWhiteSpace(request.Title))
                {
                    var keyword = request.Title.Trim();
                    query = query.Where(x => x.Title.Contains(keyword));
                }

                // 如果有开始时间
                if (request.StartTime.HasValue)
                {
                    query = query.Where(x => x.UploadTime >= request.StartTime.Value);
                }

                // 如果有结束时间
                if (request.EndTime.HasValue)
                {
                    query = query.Where(x => x.UploadTime <= request.EndTime.Value);
                }

                // 如果有状态
                if (request.Status.HasValue)
                {
                    query = query.Where(x => x.Status == request.Status.Value);
                }

                // 获取总记录数
                int totalCount = await query.CountAsync(cancellationToken);

                // 计算跳过的记录数
                int skip = (request.CurrentPage - 1) * request.PageSize;

                // 分页查询并按排序号和上传时间排序
                var carousels = await query
                    .OrderByDescending(x => x.SortOrder)
                    .ThenByDescending(x => x.UploadTime)
                    .Skip(skip)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 映射到DTO
                var carouselDtos = _mapper.Map<List<CarouselDto>>(carousels);

                // 构建分页响应
                var pageResponse = new PagedResult<CarouselDto>
                {
                    PageIndex = request.CurrentPage,
                    PageSize = request.PageSize,
                    TotalCount = totalCount,
                    Items = carouselDtos
                };

                _logger.LogInformation("成功获取到 {Count} 个轮播图信息", carouselDtos.Count);

                return new APIResult<PagedResult<CarouselDto>>
                {
                    Code = APIEnum.OK,
                    Message = "获取轮播图列表成功",
                    Data = pageResponse
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取轮播图列表时发生错误");
                return new APIResult<PagedResult<CarouselDto>>
                {
                    Code = APIEnum.Fail,
                    Message = "获取轮播图列表失败，请稍后重试",
                    Data = new PagedResult<CarouselDto>()
                };
            }
        }
    }
}